class Scheduler {
    constructor(maxConcurrent) {
        this.maxConcurrent = maxConcurrent;
        this.queue = [];
        this.currentCount = 0;
    }

    add(promise) {
        return new Promise((resolve, reject) => {
            this.queue.push(() => {
                return promise().then(resolve).catch(reject)
            });
            this.run();
        });   
    }

    // add(promise) {
    //     return new Promise((resolve, reject) => {
    //         this.queue.push(() => promise().then(resolve).catch(reject));
    //         this.run();
    //     })
    // }

    // run() {
    //     if (this.currentCount < this.maxConcurrent) {
    //         const task = this.queue.shift();
    //         if (task) {
    //             task().finally(() => {
    //                 this.currentCount--;
    //                 this.run();
    //             });
    //         }
    //     }
    // }


    run() {
        if (this.currentCount < this.maxConcurrent) {
            const task = this.queue.shift(); // 取队头元素
            if (task) {
                this.currentCount++;
                task().finally(() => {
                    this.currentCount--;
                    this.run();
                });
            }
            
        }
    }
}

const scheduler = new Scheduler(2);



function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

function task(id) {
    console.log(`Task ${id} started`);
    return delay(1000).then(() => {
        console.log(`Task ${id} completed`);
    });
}

for (let i = 0; i < 5; i++) {
    scheduler.add(() => task(i));
}


// const obj = {
//     name: 'Alice',
//     say: () => {
//         console.log("this：", this);
//         console.log(`Hello! My name is ${this.name}`);
//     }
// }

// obj.say();


// const obj1 = {
//     name: 'Alice',
//     say: function() {
//         console.log("this：", this);
//         console.log(`Hello! My name is ${this.name}`);
//     }
// }

// obj1.say()
